package gam.n1.areas.block;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import gam.n1.MathHelper;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;

import java.util.*;

public class BlockSpace implements iBox {
    private World world;
    private Set<Chunk> chunks;
    private List<Location> points;

    private double a; // 长
    private double b; // 宽
    private double c; // 高

    private Location d1;
    private Location t4;
    public BlockSpace(double a,double b, double c){
        this.a = a;
        this.b = b;
        this.c = c;
    }
    public BlockSpace(){}

    public BlockSpace(Location pA,Location pB){
        this.d1 = pA;
        this.t4 = pB;
        i(pA,pB);
    }

    @Override
    public boolean s(Location one) {
        Objects.requireNonNull(one);
        if (d1 == null) {
            d1 = one;
        } else if (t4 == null){
            t4 = one;
        }
        if (d1 != null && t4 != null){
            i(d1,t4);
            return true;
        }
        return false;
    }

    @Override
    public void i(Location a,Location b) {
        if (a.getWorld() == b.getWorld()){
            this.world = a.getWorld();
        }
        this.a = MathHelper.a(b.getX(),a.getX());
        this.b = MathHelper.a(b.getY(),a.getY());
        this.c = MathHelper.a(b.getZ(),a.getZ());
        fg();
    }
    public static iBox g(Location a, Location b){
        return new BlockSpace(a,b);
    }
    private void fg(){
        if (this.world != null){
            this.points = Arrays.asList(
                    this.d1,this.t4,
                    new Location(this.world,this.d1.getX(),this.t4.getY(),this.d1.getZ()),
                    new Location(this.world,this.t4.getX(),this.d1.getY(),this.d1.getZ()),
                    new Location(this.world,this.t4.getX(),this.t4.getY(),this.d1.getZ()),
                    new Location(this.world,this.d1.getX(),this.d1.getY(),this.t4.getZ()),
                    new Location(this.world,this.d1.getX(),this.t4.getY(),this.t4.getZ()),
                    new Location(this.world,this.t4.getX(),this.d1.getY(),this.t4.getZ())
            );
            this.chunks = new HashSet<>();
            for (Location _p : this.points) {
                this.chunks.add(this.world.getChunkAt(_p));
            }
        }
    }
    @Override
    public double a() {
        return a;
    }

    @Override
    public double b() {
        return b;
    }

    @Override
    public double c() {
        return c;
    }

    @Override
    public double vol() {
        return MathHelper.vol(a,b,c);
    }

    @Override
    public boolean compareVol(iBox box) {
        return vol() >= box.vol();
    }

    @Override
    public boolean isNotNull() {
        return d1 != null && t4 != null;
    }

    @Override
    public World w() {
        return this.world;
    }

    @Override
    public boolean ie(Entity entity) {
        boolean wt = entity.getWorld() == w();

        double x = Math.abs(entity.getLocation().getX());
        double y = Math.abs(entity.getLocation().getY());
        double z = entity.getLocation().getZ();

        double ax = MathHelper.max(d1.getX(),t4.getX());
        double ix = MathHelper.min(d1.getX(),t4.getX());
        boolean xt = x >= ix && x <= ax;

        double ay = MathHelper.max(d1.getY(),t4.getY());
        double iy = MathHelper.min(d1.getY(),t4.getY());
        boolean yt = y >= iy && y <= ay;

        double az = MathHelper.max(d1.getZ(),t4.getZ());
        double iz = MathHelper.min(d1.getZ(),t4.getZ());
        boolean zt = z >= iz && z <= az;

        return wt && xt && yt && zt;
    }

    @Override
    public Set<Chunk> cs() {
        return Collections.unmodifiableSet(this.chunks);
    }

    @Override
    public List<Location> ps() {
        return Collections.unmodifiableList(this.points);
    }

    @Override
    public Map<String,Object> save() {
        Map<String,Object> temp = Maps.newHashMap();
        temp.put("world",world.getName());
        temp.put("point1",_g(d1));
        temp.put("point2",_g(t4));
        return temp;
    }
    private String _g(Location l){
        String[] _s = new String[]{
                l.getX() + "",
                l.getY() + "",
                l.getZ() + ""
        };
        return String.join(",",_s);
    }
    public static iBox m(Map map){
        Objects.requireNonNull(map);
        World world = Bukkit.getWorld((String) map.get("world"));
        Location p1 = tl((String) map.get("point1"));
        Location p2 = tl((String) map.get("point2"));
        p1.setWorld(world);p2.setWorld(world);
        return BlockSpace.g(p1,p2);
    }
    private static Location tl(String s){
        String[] var1 = s.split(",");
        double x = Double.parseDouble(var1[0]);
        double y = Double.parseDouble(var1[1]);
        double z = Double.parseDouble(var1[2]);
        return new Location(null,x,y,z,0,0);
    }
}
